#pragma once

#include <nanobdd/bdd.h>
#include <nanobdd/cache.h>
#include <nanobdd/common.h>
#include <nanobdd/listapplycache.h>
#include <nanobdd/listnodecache.h>
// #include <nanobdd/mapcache.h>
#include <nanobdd/node.h>
// #include <nanobdd/nodecache.h>

#include <map>
#include <memory>
#include <vector>

namespace nanobdd {

class Nanobdd {
 public:
  Nanobdd(size_t cacheSize);
  // ~Nanobdd();

  Bdd& createVar(int id);
  void createVars(int num);
  static Bdd& getVar(int id);

  static Node* makeNode(
      int level, Node* low, Node* high);

  static inline Node* trueNode;
  static inline Node* falseNode;
  static auto&
  getTrueNode() {
    return trueNode;
  }
  static auto&
  getFalseNode() {
    return falseNode;
  }
  static inline std::vector<Bdd> vars_;

  auto&
  getMyCache() {
    return cache_;
  }

  static inline ListApplyCache cache_;
  // static inline Cache cache_;

  static inline int cacheSize;

 private:
  int varNum_;

  // static inline std::map<std::tuple<uint32_t, Node*, Node*>,
  // std::shared_ptr<Node>> nodecache_;
  static inline ListNodeCache nodecache_;
};

} // namespace nanobdd